<?php
require_once('Exceptions.php');
/**
 *  封装对MySQL数据库的操作。。
 */
class Db {
  private $handler;
  
  function __construct($host, $port, $user, $passwd, $db, $encode){
    $connectionDescriptor = "mysql:host=$host;port=$port;dbname=$db";
    $this->handler = new PDO($connectionDescriptor, $user, $passwd);
    if ($encode){
      $this->handler->query("SET NAMES $encode;");
    }
  }

  function __destruct(){}

  /**
   * 检查数据库连接。如果返回false，说明连接中断。
   */
  function connected(){
    $sql = "SELECT 1";
    return $this->query($sql);
  }

  /**
   * 查询SQL。查询成功返回一个数组，查询失败返回false。返回的数组中每个元素是一条记录。
   */
  function query($sql){
    if (!$this->handler){
      return false;
    }
     $resultSet = $this->handler->query($sql);
    $resultSet->setFetchMode(PDO::FETCH_ASSOC);
    $rows = $resultSet->fetchAll();
    return $rows;
  }

  /**
   * 查询数据库中的数据表。返回一个数组。
   */
  function tables(){
    $sql = "SHOW TABLES";
    $rows = $this->query($sql);
    $result = array();
    foreach ($rows as $k => $v){
      foreach ($v as $tbl){
        array_push($result, $tbl);
      }
    }
    return $result;
  }
}

/**
 *  数据表。
 */
class Table {
  function __construct($db, $name){
    $this->db = $db;
    $this->name = $name;
  }

  /**
   * 返回表中的列。
   */
  function fields(){
    $sql = "DESC ".$this->name;
    $resultSet = $this->db->query($sql);
    $fields = array();
    foreach ($resultSet as $k){
      array_push($fields, $k['Field']);
    }
    return $fields;
  }

  /**
   * 返回表中的记录数。
   */
  function count(){
    $sql = "SELECT COUNT(*) AS count FROM `".$this->name."`";
    $result = $this->db->query($sql);
    return intval($result[0]['count']);
  }

  /**
   * 查询记录。$fields是要查询的列，$conditions是查询条件，$limit是最多查询条数。
   */
  function select($fields = array(), $conditions = array(), $limit = -1){
    $sql = "SELECT ";
    if (count($fields) == 0){
      $sql .= " * ";
    } else {
      foreach ($fields as $k){
        if ($sql != "SELECT "){
          $sql .= ", ";
        }
        $sql .= $k;
      }
    }
    $sql .= " FROM ".$this->name." WHERE 1=1 ";
    foreach ($conditions as $k => $v){
      $sql .= " AND `".$k."` = \"".$v."\" ";
    }
    if ($limit != -1){
      $sql .= " LIMIT ".strval($limit);
    }
    $rows = array();
    $rows = $this->db->query($sql);
    return $rows;
  }

  /**
   * 更新记录。$fields是要查询的列，$values是要更新的值，
   * $conditions是查询条件，$limit是最多更新条数。
   */
  function update($fields, $values, $conditions, $limit = -1){
    if (count($fields) != count($values) || count($fields) == 0){
      return false;
    }
    $number = count($fields);
    $sql = "UPDATE `".$this->name."` SET ";
    for ($i = 0; $i < $number; ++$i){
      $field = $fields[$i];
      $value = $values[$i];
      if ($i > 0){
        $sql .= ", ";
      }
      $sql .= "\"".$field."\" = \"".$value."\"";
    }
    $sql .= " WHERE 1=1 ";
    foreach ($conditions as $k => $v){
      $sql .= " AND \"".$k."\" = \"".$v."\" ";
    }
    if ($limit != -1){
      $sql .= " LIMIT ".$limit;
    }
    return $this->db->query($sql);
  }

  /**
   * 删除记录。$conditions是条件，$limit是最多删除条数。
   */
  function delete($conditions, $limit = -1){
    $sql = "DELETE FROM `".$this->name."` WHERE 1=1 ";
    foreach ($conditions as $k => $v){
      $sql .= " AND `".$k."` = \"".$v."\"";
    }
    if ($limit != -1){
      $sql .= " LIMIT ".$limit;
    }
    return $this->db->query($sql);
  }

  /**
   * 截断数据表。
   */
  function truncate(){
    $sql = "truncate ".$this->name;
    return $this->db->query($sql);
  }
  
  /**
   * 插入记录。$fields是字段，$values是值。
   */
  function insert($fields, $values){
    if (count($values) == 0){
      return false;
    }
    $sql = "INSERT INTO `".$this->name."`";
    $count = count($fields);
    if ($count > 0){
      $sql .= " (";
      for ($i = 0; $i < $count; ++$i){
        if ($i > 0){
          $sql .= ", ";
        }
        $sql .= $fields[$i];
      }
      $sql .= ") ";
    }    
    $sql .= " VALUES (";
    $count = count($values);
    for ($i = 0; $i < $count; ++$i){
      if ($i > 0){
        $sql .= ", ";
      }
      $sql .= "\"".$values[$i]."\"";
    }
    $sql .= ")";
    return $this->db->query($sql);
  }

  private $db;    // 数据库
  private $name;  // 数据表名
}

?>